module Grape
  module Util
    class ParamType
      @type_mapper = {
        [Integer, 'Integer', 'integer'] => Integer,
        [Float, 'Float', 'float'] => Float,
        [BigDecimal, 'BigDecimal'] => BigDecimal,
        [Numeric, 'Numeric', 'number'] => Numeric, 
        [Date, 'Date', 'date'] => Date,
        [DateTime, 'DateTime', 'datetime'] => DateTime, 
        [Time, 'Time', 'time'] => Time, 
        [Grape::API::Boolean, 'Boolean', 'boolean'] => Grape::API::Boolean,
        [String, 'String', 'string'] => String, 
        [Symbol, 'Symbol', 'symbol'] => Symbol, 
        [Rack::Multipart::UploadedFile, File, 'File', 'file'] => Rack::Multipart::UploadedFile,
        [JSON, 'JSON', 'json'] => JSON, 
        [Hash, 'Hash', 'hash', Object, 'Object', 'object'] => Hash,
        [Array, 'Array', 'array'] => Array
      }.map do |keys, value|
        keys.zip([value] * keys.length)
      end.flatten(1).to_h.freeze

      class << self
        attr_reader :type_mapper

        def map_type(type)
          if type_mapper.key?(type)
            type_mapper[type]
          elsif type.is_a?(Array)
            Array
          else
            type = Object.const_get(type) if type.is_a?(String) && Object.const_defined?(type)
            type = Hash if type.is_a?(Class) && type < Grape::Entity
            type
          end
        end
      end
    end
  end
end
